package com.henghe.frame.auth.runner;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.henghe.frame.auth.entity.SysPermission;
import com.henghe.frame.auth.entity.SysRolePermission;
import com.henghe.frame.auth.mapper.SysPermissionMapper;
import com.henghe.frame.auth.mapper.SysRolePermissionMapper;
import com.henghe.frame.common.annotation.OptLog;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Description:
 * Author: LiuWenQing
 * Datetime: 2023/4/4 14:02
 */
@Slf4j
@Component
@Order(10)
public class AuthApplicationListener implements ApplicationListener<ContextRefreshedEvent> {

    private static final String REQUEST_BEAN_NAME = "requestMappingHandlerMapping";

    @Resource
    private SysPermissionMapper sysPermissionMapper;
    @Resource
    private SysRolePermissionMapper sysRolePermissionMapper;

    @Value("${henghe.auth-runner.active}")
    private Boolean authActive;

//    @Resource
//    private ScBusinessOptApiAuthMapper scBusinessOptApiAuthMapper;
//    @Resource
//    private ScBusinessOptAuthMapper scBusinessOptAuthMapper;
//    @Resource
//    private CommUtil commUtil;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (!authActive) {
            log.info("未开启扫描权限注解配置，扫描跳过");
            return;
        }
        log.info("{}存在，开始扫描controller方法", REQUEST_BEAN_NAME);
        // 判断RequestMappingHandlerMapping是否存在，若不存在则不扫描
        ApplicationContext applicationContext = event.getApplicationContext();
        if (!applicationContext.containsBean(REQUEST_BEAN_NAME)) {
            log.info("{}不存在, 扫描跳过", REQUEST_BEAN_NAME);
            return;
        }
        // 获取所有的接口方法信息
        RequestMappingHandlerMapping requestMapping =
                applicationContext.getBean(REQUEST_BEAN_NAME, RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> infoMap = requestMapping.getHandlerMethods();
        List<SysPermission> permissions = new ArrayList<>();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : infoMap.entrySet()) {
            HandlerMethod method = entry.getValue();
            OptLog optLog = method.getMethodAnnotation(OptLog.class);
            if (optLog != null) {
                String logValue = optLog.value(); // 业务描述
                if (StringUtils.isBlank(logValue))// 获取日志默认描述，未定义时 使用swagger注解描述
                    logValue = method.getMethodAnnotation(ApiOperation.class).value();
                String code = optLog.code(); // 接口权限标识
                // 权限标识为空的，不扫描
                if (StringUtils.isEmpty(code))
                    continue;
                if (!permissions.stream().anyMatch(e -> e.getPermissionCode().equals(code))) {
                    permissions.add(SysPermission.builder()
                            .permissionName(logValue)
                            .permissionCode(code)
                            .useStatus(optLog.valid() ? 1 : 0)
                            .permissionTypeId(1)
                            .build());
                }
            }
        }
        List<SysPermission> dbPermissions = sysPermissionMapper.selectList(null);
        List<SysPermission> removeList = dbPermissions.stream().filter(e ->
                permissions.stream().filter(i -> i.getPermissionCode().equals(e.getPermissionCode())).count() < 1).collect(Collectors.toList());
        removeList.forEach(e -> {
            sysRolePermissionMapper.delete(new QueryWrapper<SysRolePermission>().eq("permission_id", e.getId()));
            sysPermissionMapper.deleteById(e);
        });
        //过滤出要新增的权限
        List<SysPermission> saveList = permissions.stream().filter(e ->
                        dbPermissions.stream().filter(i -> i.getPermissionCode().equals(e.getPermissionCode())).count() < 1)
                .collect(Collectors.toList());
        //去重
        saveList = saveList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<SysPermission>(Comparator.comparing(o -> o.getPermissionCode()))), ArrayList::new));
        saveList.forEach(e -> sysPermissionMapper.insert(e));
    }
}
